#include <types.h>
#include <sys_config.h>
#include <retcode.h>
#include <api/libc/string.h>
#include <api/libc/printf.h>
#include <osal/osal.h>
#include <api/libmp/pe.h>
#include "image_engine.h"
#include "plugin.h"

extern ImagePlugin jpeg_plugin;
extern ImagePlugin png_plugin;
extern ImagePlugin gif_plugin;

#ifdef SEE_CPU
void hld_cpu_img_cb(unsigned long type, unsigned long param);
#endif

static ImagePlugin* plugins[] = 
{
	&jpeg_plugin,
	&gif_plugin,
	&png_plugin,
	NULL,
};

#define IMAGE_STATE_STOP		0
#define IMAGE_STATE_DECODE		1
#define IMAGE_STATE_SHOW		2

struct image_plugin_data
{
	unsigned long	state;
	ImagePlugin 	*plugin;
};

struct image_plugin_data image_plugin_data;


static ImagePlugin *get_current_plugin(void)
{
	return image_plugin_data.plugin;
}

OSAL_ID flag_image;

static mp_callback_func func_mp_cb;
int image_engine_init(struct pe_image_cfg *pe_image_cfg)
{
	ImagePlugin *plugin;
	ImagePlugin **head;

#ifdef SEE_CPU
    if(pe_image_cfg->mp_cb)
        func_mp_cb = hld_cpu_img_cb;
    else
#endif
    {
	    func_mp_cb = pe_image_cfg->mp_cb;
    }

	
	for(head = plugins;plugin = *head; head++)
	{
		if(plugin->init)
			plugin->init(pe_image_cfg);
		
	}
	
	return 0;
	
}

int image_engine_cleanup()
{
	ImagePlugin *plugin;
	ImagePlugin **head = plugins;
	
	for(head = plugins;plugin = *head; head++)
	{
		if(plugin->cleanup)
			plugin->cleanup();
		
	}
	return 0;
}

int image_engine_rotate(unsigned char rotate_angle)
{
	ImagePlugin *plugin;
	ImagePlugin **head;
	int ret = -1;

	for(head = plugins; plugin = *head; head ++)
	{
		if(plugin->rotate)
			ret = plugin->rotate(rotate_angle);
	}
	return ret;
}

int image_engine_decode(char *filename, struct image_config *cfg)
{
	int ret = -1;
	BOOL try_image_decoder = TRUE;
	ImagePlugin *plugin;
	ImagePlugin **head = plugins;
	struct image_display_t *dis = (struct image_display_t *)cfg;

	for(head = plugins;plugin = *head; head++)
	{
		if(plugin->is_our_file(filename))
		{
			try_image_decoder = FALSE;
			break;
		}
	}

	if(try_image_decoder) goto LBL_OTHER_IMAGE_DECODER;
	
	if(plugin == NULL)
		return -1;
	
	MEMSET(&image_plugin_data, 	0, sizeof(struct image_plugin_data));
	image_plugin_data.plugin = plugin;

	if((image_plugin_data.plugin) && (image_plugin_data.plugin->decode))
	{
	 	if (3 == strlen(filename)  && !strcasecmp(filename, "YUV")) 
	 	{
	 		dis->mp_cb = func_mp_cb;
	 		ret = plugin->decode(filename, dis);
	 	}
		else
		{
			cfg->mp_cb = func_mp_cb;
			ret = plugin->decode(filename, cfg);
		}
	}
	if(ret == 0)
		image_plugin_data.state = IMAGE_STATE_DECODE;
	else
	{
		try_image_decoder = TRUE;
		goto LBL_OTHER_IMAGE_DECODER;
	}
	
	return ret;

LBL_OTHER_IMAGE_DECODER:

	head = plugins;
	while( NULL != *head && try_image_decoder)
	{
		plugin = *head;

		if( plugin == NULL )
			return -1;
		
		MEMSET(&image_plugin_data, 	0, sizeof(struct image_plugin_data));
		image_plugin_data.plugin = plugin;

		if((image_plugin_data.plugin) && (image_plugin_data.plugin->decode))
		{

			cfg->mp_cb = func_mp_cb;
			ret = plugin->decode(filename, cfg);
		}

		if(ret == 0)
		{
			image_plugin_data.state = IMAGE_STATE_DECODE;
			try_image_decoder = FALSE;
			break;
		}
		head++;
	}

	return ret;
}

int image_engine_show()
{
	if(image_plugin_data.state != IMAGE_STATE_DECODE)
	{
		return -1;
	}
	if((image_plugin_data.plugin) && (image_plugin_data.plugin->show))
	{
		image_plugin_data.plugin->show();
	}
	image_plugin_data.state = IMAGE_STATE_SHOW;
	return 0;
}

int image_engine_abort()
{
/*	if(image_plugin_data.state != IMAGE_STATE_DECODE)
	{
		return -1;
	}
*/	if((image_plugin_data.plugin) && (image_plugin_data.plugin->abort))
	{
		image_plugin_data.plugin->abort();
	}
	image_plugin_data.state = IMAGE_STATE_STOP;
	return 0;
	
}
int image_engine_2d_to_3d_swap(int type)
{
    if((image_plugin_data.plugin) && (image_plugin_data.plugin->swap))
	{
		image_plugin_data.plugin->swap(type);
	}
	
	return 0;
}


int image_engine_3d_user_option(struct image_3d_para *para)
{
    int output_format = para->output_format;
    int user_depth = para->user_depth;
    int user_shift = para->user_shift;
    int user_vip = para->user_vip;
    if((image_plugin_data.plugin) && (image_plugin_data.plugin->option))
	{
		image_plugin_data.plugin->option(output_format, user_depth, user_shift, user_vip);
	}
	
	return 0;
}

int image_engine_set_disp_param(int display_type, struct image_3d_para *para)
{
    int output_format = para->output_format;
    int user_depth = para->user_depth;
    int user_shift = para->user_shift;
    int user_vip = para->user_vip;
    if((image_plugin_data.plugin) && (image_plugin_data.plugin->option))
	{
		image_plugin_data.plugin->set_param(display_type, output_format, user_depth, user_shift, user_vip);
	}
	
	return 0;
}


int image_engine_zoom(struct Rect *dstRect, struct Rect *srcRect)
{
	if((image_plugin_data.plugin) && (image_plugin_data.plugin->zoom))
		image_plugin_data.plugin->zoom(dstRect, srcRect);
	
}

int image_engine_get_info(char *filename, struct image_info *info)
{
	int ret = -1;
	ImagePlugin *plugin;
	ImagePlugin **head = plugins;
		
	for(head = plugins;plugin = *head; head++)
	{
		if(plugin->is_our_file(filename))
			break;
		
	}
	
	if(plugin == NULL)
		return -1;
	
	if(plugin->get_info)
	{
		ret  = plugin->get_info(filename, info);
	}
	return ret;
	
}




